package com.bdk.middle.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdk.middle.management.api.domain.MenuDO;
import com.bdk.middle.management.api.domain.PermissionDO2;
import com.bdk.middle.management.core.entity.*;
import com.bdk.middle.management.core.mapper.AdminMapper;
import com.bdk.middle.management.core.mapper.AdminRoleMapper;
import com.bdk.middle.management.core.mapper.PermissionMapper;
import com.bdk.middle.management.core.mapper.RolePermissionMapper;
import com.bdk.middle.management.api.domain.PermissionDO;
import com.bdk.middle.management.api.query.PermissionQueryDO;
import com.bdk.middle.common.status.ErrorCode;
import com.bdk.middle.common.domain.PageDO;
import com.bdk.middle.common.result.ResultDO;
import com.bdk.middle.common.util.BeanUtilsExtends;
import com.bdk.middle.common.util.Constant;
import com.bdk.middle.management.service.AdminService;
import com.bdk.middle.management.service.PermissionService;
import com.bdk.middle.management.service.RoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 权利 服务实现类
 * </p>
 *
 * @author Reagan
 * @since 2021-01-23
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, PermissionEntity> implements PermissionService {

    public static final String SUPER_ADMIN_ROLE="superadmin";
    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private PermissionMapper        permissionMapper;

    @Autowired
    private RolePermissionMapper    rolePermissionMapper;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AdminService adminService;

    /**
     * 获取系统用户权限字符串集合
     * @author chang
     *
     * @param sysUserName 系统用户名
     * @return
     */
    @Override
    public ResultDO getPermissionByUsername(String sysUserName){
        ResultDO result = new ResultDO();
        Set<String> permissionSet = new HashSet<>();
        //查用户id
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("username",sysUserName);
        wrapper.eq("is_delete",Constant.IS_DELETE_FALSE);
        AdminEntity sysUserRecord =adminMapper.selectOne(wrapper);
        if(sysUserRecord==null){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }
        //查角色
        QueryWrapper wrapper2 = new QueryWrapper();
        wrapper2.eq("user_id",sysUserRecord.getId());
        List<AdminRoleEntity> adminRoleRecords =adminRoleMapper.selectList(wrapper2);

        //根据角色查权限字符串，组装
        try {
            for(AdminRoleEntity adminRoleRecord:adminRoleRecords){
                QueryWrapper wrapper3 = new QueryWrapper();
                wrapper3.eq("role_id",adminRoleRecord.getRoleId());
                List<RolePermissionEntity> rolePermissionRecords =rolePermissionMapper.selectList(wrapper3);

                for(RolePermissionEntity rolePermissionRecord:rolePermissionRecords){
                    QueryWrapper wrapper4 = new QueryWrapper();
                    wrapper4.eq("id",rolePermissionRecord.getPermissionId());
                    PermissionEntity permissionRecord=permissionMapper.selectOne(wrapper4);
                    if(permissionRecord!=null){
                        permissionSet.add(permissionRecord.getCode());
                    }

                }
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, permissionSet);
        return result;
    }

    @Override
    @Transactional
    public ResultDO add(PermissionDO domain) {

        PermissionEntity entity = new PermissionEntity();
        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setCreateDate(Calendar.getInstance().getTime());
        entity.setModifiDate(entity.getCreateDate());
        entity.setModifier(entity.getCreator());

        int res = -1;
        try {
            res = permissionMapper.insert(entity);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PERMISSION_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }


        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PERMISSION_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.PERMISSION_ADD_ERROR.getCode() + " msg" + ErrorCode.PERMISSION_ADD_ERROR.getMsg());
            return result;
        }
        //给管理员添加该权限
        //AdminEntity adminRecord=adminService.getAdminUser("");
        //String roleId=roleService.getRoleIdByUserId();
        RoleEntity superadminRoleRecord =roleService.getRoleByCode(SUPER_ADMIN_ROLE);

        RolePermissionEntity rolePermissionEntity = new RolePermissionEntity();
        rolePermissionEntity.setRoleId(superadminRoleRecord.getId());
        rolePermissionEntity.setPermissionId(entity.getId());
        rolePermissionMapper.insert(rolePermissionEntity);
        return result;
    }

    public ResultDO bindPermissions(String roleId, List<String> permissionIds) {
        ResultDO result = new ResultDO();

        for(String permissionId : permissionIds) {
            RolePermissionEntity entity = new RolePermissionEntity();
            entity.setRoleId(roleId);
            entity.setPermissionId(permissionId);
            int res = -1;
            try {
                res = rolePermissionMapper.insert(entity);
            } catch (Exception e) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
                logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
                return result;
            }

            //判断r的值是否小于0.如果小于0 就代表添加失败
            if(res < 0) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.PERMISSION_BIND_ROLE_ERROR);
                logger.debug("error code：" + ErrorCode.PERMISSION_BIND_ROLE_ERROR.getCode() + " msg" + ErrorCode.PERMISSION_BIND_ROLE_ERROR.getMsg());
                return result;
            }
        }
        return result;
    }

    public ResultDO unbindPermissions(String roleId) {

        ResultDO result = new ResultDO();

        int res = -1;
        try {
            res = rolePermissionMapper.delete(Wrappers.<RolePermissionEntity>lambdaQuery().eq(RolePermissionEntity::getRoleId, roleId));
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PERMISSION_UNBIND_ROLE_ERROR);
            logger.debug("error code：" + ErrorCode.PERMISSION_UNBIND_ROLE_ERROR.getCode() + " msg" + ErrorCode.PERMISSION_UNBIND_ROLE_ERROR.getMsg());
            return result;
        }

        return result;
    }


    @Override
    public ResultDO edit(PermissionDO domain) {

        PermissionEntity entity = new PermissionEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        entity.setModifiDate(Calendar.getInstance().getTime());

        int res = -1;
        try {
            res = permissionMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PERMISSION_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.PERMISSION_EDIT_ERROR.getCode() + " msg" + ErrorCode.PERMISSION_EDIT_ERROR.getMsg());
            return result;
        }

        return result;
    }



    @Override
    public ResultDO get(String id) {
        ResultDO result = new ResultDO();

        PermissionEntity entity = null;

        try {
            entity = permissionMapper.selectById(id);
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        PermissionDO domain = getDomain(entity);

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }

    @Override
    public ResultDO remove(String id, String modifier) {

        ResultDO result = new ResultDO();

        PermissionEntity entity = new PermissionEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(modifier);
        entity.setId(id);
        entity.setIsDelete(Constant.IS_DELETE);

        int res = -1;
        try {
            res = permissionMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.PERMISSION_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.PERMISSION_DELETE_ERROR.getCode() + " msg" + ErrorCode.PERMISSION_DELETE_ERROR.getMsg());
            return result;
        }

        return result;
    }

    @Override
    public ResultDO find(PermissionQueryDO query) {

        PermissionEntity entity = new PermissionEntity();

        ResultDO result = BeanUtilsExtends.copy(entity,query);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        QueryWrapper<PermissionEntity> wrapper = new QueryWrapper<PermissionEntity>(entity);

        Page<PermissionEntity> page = new Page<>(query.getCurrentPage(),query.getPageSize());
        IPage<PermissionEntity> iPage = null;
        try {
            iPage = permissionMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        List<PermissionDO> doList = getDomainList(iPage.getRecords());

        PageDO<PermissionDO> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    private PermissionDO getDomain(PermissionEntity entity) {
        ResultDO result = new ResultDO();
        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        PermissionDO domain = new PermissionDO();

        if(!result.isSuccess()) {
            return null;
        }
        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }


    private  List<PermissionDO> getDomainList(List<PermissionEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<PermissionDO> doList = new ArrayList<>();

        //判断传入的list的集合的size是否大于0
        if(list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for(PermissionEntity entity : list) {

                PermissionDO domain = this.getDomain(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if(domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }

    /**
     * 查角色菜单，一级和二级菜单
     * @param roleId 权限id
     * @return ResultDO
     */
    @Override
    public  List<MenuDO> getMenusByRoleId(String roleId){
        List<MenuDO> menus=new ArrayList<>();
        //查角色权限关联表
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("role_id",roleId);
        List<RolePermissionEntity> rolePermRecords =rolePermissionMapper.selectList(wrapper);
        if(rolePermRecords.isEmpty()){
            return null;
        }
        //组装
        List<String> permissionIds=new ArrayList<>();

        for(RolePermissionEntity item:rolePermRecords){
            permissionIds.add(item.getPermissionId());
        }
        QueryWrapper wrapper2 = new QueryWrapper();
        wrapper2.in("id",permissionIds);
        wrapper2.eq("is_delete",Constant.IS_DELETE_FALSE);
        wrapper2.orderByDesc("sort");
        List<PermissionEntity> permissionEntities=permissionMapper.selectList(wrapper2);
        if(permissionEntities==null){
            return null;
        }
        //一级菜单组装
        for(PermissionEntity item:permissionEntities){
            if(item.getPermissionId()==null || StringUtils.isEmpty(item.getPermissionId())){
                MenuDO m=new MenuDO();
                m.setId(item.getId());
                m.setCode(item.getCode());
                m.setPermissionId(item.getPermissionId());
                m.setName(item.getName());
                m.setType(item.getType());
                m.setRequestUrl(item.getRequestUrl());
                m.setIcon(item.getIcon());
                m.setSort(item.getSort());
                //二级菜单追加到一级菜单
                for(PermissionEntity item2:permissionEntities) {
                   if(item2.getPermissionId()==null || StringUtils.isEmpty(item2.getPermissionId())){
                     continue;
                   }
                   if(item2.getPermissionId().equals(item.getId())){
                       MenuDO subMenu=new MenuDO();
                       subMenu.setId(item2.getId());
                       subMenu.setCode(item2.getCode());
                       subMenu.setPermissionId(item2.getPermissionId());
                       subMenu.setName(item2.getName());
                       subMenu.setType(item2.getType());
                       subMenu.setRequestUrl(item2.getRequestUrl());
                       subMenu.setIcon(item2.getIcon());
                       subMenu.setSort(item2.getSort());

                       m.getSubMenus().add(subMenu);
                   }
                }
                menus.add(m);
            }
        }
        return menus;
    }

    /**
     * 角色权限列表
     * @param roleId 角色id
     * @return
     */
    @Override
    public List<PermissionDO2> getPermissionByRoleId(String roleId){
        List<PermissionDO2> permissions=new ArrayList<>();
        //查角色权限关联表
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("role_id",roleId);
        List<RolePermissionEntity> rolePermRecords =rolePermissionMapper.selectList(wrapper);
        if(rolePermRecords.isEmpty()){
            return null;
        }
        //组装
        List<String> permissionIds=new ArrayList<>();

        for(RolePermissionEntity item:rolePermRecords){
            permissionIds.add(item.getPermissionId());
        }
        QueryWrapper wrapper2 = new QueryWrapper();
        wrapper2.in("id",permissionIds);
        wrapper2.eq("is_delete",Constant.IS_DELETE_FALSE);
        wrapper2.orderByDesc("sort");
        List<PermissionEntity> permissionEntities=permissionMapper.selectList(wrapper2);
        if(permissionEntities==null){
            return null;
        }
        //一级权限组装
        for(PermissionEntity item:permissionEntities){
            if(item.getPermissionId()==null || StringUtils.isEmpty(item.getPermissionId())){
                PermissionDO2 m=new PermissionDO2();
                m.setId(item.getId());
                m.setCode(item.getCode());
                m.setPermissionId(item.getPermissionId());
                m.setName(item.getName());
                m.setType(item.getType());
                m.setRequestUrl(item.getRequestUrl());
                m.setIcon(item.getIcon());
                m.setSort(item.getSort());
                //子权限追加到父权限
                for(PermissionEntity item2:permissionEntities) {
                    if(item2.getPermissionId()==null || StringUtils.isEmpty(item2.getPermissionId())){
                        continue;
                    }
                    if(item2.getPermissionId().equals(item.getId())){
                        PermissionDO2 subMenu=new PermissionDO2();
                        subMenu.setId(item2.getId());
                        subMenu.setCode(item2.getCode());
                        subMenu.setPermissionId(item2.getPermissionId());
                        subMenu.setName(item2.getName());
                        subMenu.setType(item2.getType());
                        subMenu.setRequestUrl(item2.getRequestUrl());
                        subMenu.setIcon(item2.getIcon());
                        subMenu.setSort(item2.getSort());

                        m.getSubPermissions().add(subMenu);
                    }
                }
                permissions.add(m);
            }
        }
        return permissions;
    }


}
